package com.cskaoyan.javase.object._5clone;

/**
 * > 深度克隆练习：请完成类FirstLevel的深度克隆。
 * > >  现在有三个类 FirstLevel 、SecondLevel 、ThirdLevel
 * > FirstLevel 类有三个属性：
 * >FirstLevel 属性
 * > int firstIntValue;
 * > double firstDoubleValue;
 * > SecondLevel second;
 * >
 * > SecondLevel 类有三个属性：
 SecondLevel 属性
 * >
 * > int firstIntValue;
 * > double firstDoubleValue;
 * > SecondLevel second;
 * >
 * > ThirdLevel 类有两个属性：
 * >
 * > int thirdIntValue;
 * > double thirdDouleValue;
 *
 * @since 17:21
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo3 {
    public static void main(String[] args) throws CloneNotSupportedException {
        FirstLevel first = new FirstLevel(10, 20, new SecondLevel(100, 200, new ThirdLevel(1000, 2000, "老王")));
        FirstLevel cloneFirst = first.clone();

        System.out.println(first);
        System.out.println(cloneFirst);

        System.out.println("-----------------");
        System.out.println(first.second);
        System.out.println(cloneFirst.second);

        System.out.println("------------------");
        System.out.println(first.second.third);
        System.out.println(cloneFirst.second.third);

        System.out.println("--------------------");
        /*System.out.println(first.second.third.name);
        System.out.println(cloneFirst.second.third.name);
        System.out.println("hello");*/


        first.second.third.name = "法外狂徒-张三";
        System.out.println(cloneFirst.second.third.name);
    }
}

class FirstLevel implements java.lang.Cloneable {
    int firstIntValue;
    double firstDoubleValue;
    SecondLevel second;

    @Override
    protected FirstLevel clone() throws CloneNotSupportedException {
        // 1.深度克隆要在浅克隆基础上进行
        FirstLevel cloneFirst = (FirstLevel) super.clone();
        // 2.克隆一份second引用指向的对象
        SecondLevel cloneSecond = this.second.clone();
        // 3.将克隆引用指向克隆后的新对象
        cloneFirst.second = cloneSecond;
        return cloneFirst;
    }

    public FirstLevel(int firstIntValue, double firstDoubleValue, SecondLevel second) {
        this.firstIntValue = firstIntValue;
        this.firstDoubleValue = firstDoubleValue;
        this.second = second;
    }
}

class SecondLevel implements java.lang.Cloneable {
    int firstIntValue;
    double firstDoubleValue;
    ThirdLevel third;

    @Override
    protected SecondLevel clone() throws CloneNotSupportedException {
        SecondLevel cloneSecond = (SecondLevel) super.clone();
        cloneSecond.third = this.third.clone();
        return cloneSecond;
    }

    public SecondLevel(int firstIntValue, double firstDoubleValue, ThirdLevel third) {
        this.firstIntValue = firstIntValue;
        this.firstDoubleValue = firstDoubleValue;
        this.third = third;
    }
}

class ThirdLevel implements java.lang.Cloneable {
    int thirdIntValue;
    double thirdDoubleValue;
    String name;

    @Override
    protected ThirdLevel clone() throws CloneNotSupportedException {
        return (ThirdLevel) super.clone();
    }

    public ThirdLevel(int thirdIntValue, double thirdDoubleValue, String name) {
        this.thirdIntValue = thirdIntValue;
        this.thirdDoubleValue = thirdDoubleValue;
        this.name = name;
    }
}